package tagcloud.gui;

import javax.swing.JPanel;
import javax.swing.JApplet;
import javax.swing.SwingWorker;

import tagcloud.core.Word;

import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

public class MakerApplet extends JApplet implements ActionListener {

	private static final long serialVersionUID = 1L;
	
	private CardLayout cardLayout = null;
	private JPanel cardPanel = null;
	private LoginPanel loginPanel = null;
	private ProgressPanel progressPanel = null;
	private TagCloudPanel tagCloudPanel = null;
	private ErrorPanel errorPanel = null;
	private WordSelectionPanel wordSelectionPanel = null;
	private FileChooserPanel fileChooserPanel = null;
	private OutputPanel outputPanel = null;
	
	/**
	 * This is the xxx default constructor
	 */
	public MakerApplet() {
		super();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	public void init() {
		try {
	        javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
	            public void run() {
	        		setSize(640, 480);
	        		setLayout(new CardLayout());
	        		setContentPane(getCardPanel());
	            }
	        });
	    } catch (Exception e) {
	        System.err.println("createGUI didn't successfully complete");
	    }
	}

	/**
	 * This method initializes cardPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getCardPanel() {
		if (cardPanel == null) {
			cardPanel = new JPanel();
			cardLayout = new CardLayout();
			cardPanel.setLayout(cardLayout);
			cardPanel.add(getLoginPanel(), getLoginPanel().getName());
			cardPanel.add(getProgressPanel(), getProgressPanel().getName());
			cardPanel.add(getErrorPanel(), getErrorPanel().getName());
			cardPanel.add(getTagCloudPanel(), getTagCloudPanel().getName());
			cardPanel.add(getWordSelectionPanel(), getWordSelectionPanel().getName());
			cardPanel.add(getFileChooserPanel(), getFileChooserPanel().getName());
			cardPanel.add(getOutputPanel(), getOutputPanel().getName());
			cardLayout.show(cardPanel, getLoginPanel().getName());
		}
		return cardPanel;
	}

	/**
	 * This method initializes loginPanel1	
	 * 	
	 * @return tagcloud.gui.LoginPanel	
	 */
	private LoginPanel getLoginPanel() {
		if (loginPanel == null) {
			loginPanel = new LoginPanel(this);
			loginPanel.setName("loginPanel1");
		}
		return loginPanel;
	}

	/**
	 * This method initializes progressPanel	
	 * 	
	 * @return tagcloud.gui.ProgressPanel	
	 */
	private ProgressPanel getProgressPanel() {
		if (progressPanel == null) {
			progressPanel = new ProgressPanel();
			progressPanel.setName("progressPanel");
		}
		return progressPanel;
	}

	/**
	 * This method initializes tagCloudPanel	
	 * 	
	 * @return tagcloud.gui.TagCloudPanel	
	 */
	private TagCloudPanel getTagCloudPanel() {
		if (tagCloudPanel == null) {
			tagCloudPanel = new TagCloudPanel(this);
			tagCloudPanel.setName("tagCloudPanel");
		}
		return tagCloudPanel;
	}

	/**
	 * This method initializes errorPanel	
	 * 	
	 * @return tagcloud.gui.ErrorPanel	
	 */
	private ErrorPanel getErrorPanel() {
		if (errorPanel == null) {
			errorPanel = new ErrorPanel(this);
			errorPanel.setName("errorPanel");
		}
		return errorPanel;
	}

	/**
	 * This method initializes wordSelectionPanel	
	 * 	
	 * @return tagcloud.gui.WordSelectionPanel	
	 */
	private WordSelectionPanel getWordSelectionPanel() {
		if (wordSelectionPanel == null) {
			wordSelectionPanel = new WordSelectionPanel(this);
			wordSelectionPanel.setName("wordSelectionPanel");
		}
		return wordSelectionPanel;
	}

	/**
	 * This method initializes fileChooserPanel	
	 * 	
	 * @return tagcloud.gui.FileChooserPanel	
	 */
	private FileChooserPanel getFileChooserPanel() {
		if (fileChooserPanel == null) {
			fileChooserPanel = new FileChooserPanel();
			fileChooserPanel.setName("fileChooserPanel");
		}
		return fileChooserPanel;
	}

	/**
	 * This method initializes outputPanel	
	 * 	
	 * @return tagcloud.gui.OutputPanel	
	 */
	private OutputPanel getOutputPanel() {
		if (outputPanel == null) {
			outputPanel = new OutputPanel(this);
			outputPanel.setName("outputPanel");
		}
		return outputPanel;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == getLoginPanel().getLoginButton()) {
			getLoginPanel().getLoginButton().setEnabled(false);
			(new LoginWorker()).execute();
			
		} else if(e.getSource() == getTagCloudPanel().getLogoutButton()) {
			cardLayout.show(getCardPanel(), getLoginPanel().getName());
			
		} else if(e.getSource() == getTagCloudPanel().getNextButton()) {
			(new CalculateFrequencyWorker()).execute();
			
		} else if(e.getSource() == getWordSelectionPanel().getBackButton()) {
			cardLayout.show(getCardPanel(), getTagCloudPanel().getName());
			
		} else if(e.getSource() == getWordSelectionPanel().getGenerateButton()) {
			(new GenerateCloudWorker()).execute();
			
		} else if(e.getSource() == getErrorPanel().getOkButton()) {
			cardLayout.show(getCardPanel(), getErrorPanel().getReturnCardName());
			
		} else if(e.getSource() == getTagCloudPanel().getUploadButton()) {
			getFileChooserPanel().reset();
			(new ChooseFileWorker()).execute();
			cardLayout.show(getCardPanel(), getFileChooserPanel().getName());
			
		} else if(e.getSource() == getOutputPanel().getDoneButton()) {
			cardLayout.show(getCardPanel(), getTagCloudPanel().getName());
			
		}
	}
	
	///////////////////////////////////////
	// Worker tasks, which execute extensive logic so that the GUI remains operational during computation
	///////////////////////////////////////
	
	class LoginWorker extends SwingWorker<Integer, Void> {
		private static final int LOGIN_SUCCESS = 0;
		
		@Override
		protected Integer doInBackground() throws Exception {
			//TODO: Add server connection and login logic
			getProgressPanel().setMessage("Connecting to server...");
			cardLayout.show(getCardPanel(), getProgressPanel().getName());
			Thread.sleep(1000);
			getProgressPanel().setMessage("Logging in...");
			cardLayout.show(getCardPanel(), getProgressPanel().getName());
			Thread.sleep(1000);
			return LOGIN_SUCCESS;
		}
		
		@Override
		protected void done() {
			try {
				switch(get()) {
				case LOGIN_SUCCESS:
					cardLayout.show(getCardPanel(), getTagCloudPanel().getName());
					break;
				default:
					getErrorPanel().setReturnCardName(getLoginPanel().getName());
					getErrorPanel().setError("Unkown Login Error", "The system was unable to establish a connection to the Tag Cloud server or was otherwise unable to login. Please try again soon.");
					cardLayout.show(getCardPanel(), getErrorPanel().getName());
					break;
				}
			} catch (Exception e) { }
			getLoginPanel().getLoginButton().setEnabled(true);
		}
	}

	class ChooseFileWorker extends SwingWorker<File, Void> {

		@Override
		protected File doInBackground() throws Exception {
			while(!getFileChooserPanel().selectionHasBeenMade()) {
				Thread.sleep(10);
			}
			return getFileChooserPanel().selectedFile();
		}
		
		@Override
		protected void done() {
			try {
				if(get() != null) {
					(new UploadFileWorker()).execute();
				} else {
					cardLayout.show(getCardPanel(), getTagCloudPanel().getName());
				}
			} catch (Exception e) { }
		}
		
	}
	
	class UploadFileWorker extends SwingWorker<Boolean, Void> {

		@Override
		protected Boolean doInBackground() throws Exception {
			getProgressPanel().setMessage("Reading text file...");
			cardLayout.show(getCardPanel(), getProgressPanel().getName());
			
			//TODO: Add file input to load text
			Thread.sleep(1000);
			return true;
		}
		
		@Override
		protected void done() {
			try {
				if(get()) {
					cardLayout.show(getCardPanel(), getTagCloudPanel().getName());
				} else {
					getErrorPanel().setReturnCardName(getTagCloudPanel().getName());
					getErrorPanel().setError("File Error", "Unable to read or access the chosen file. Please ensure Java has permission to access the file and try again.");
					cardLayout.show(getCardPanel(), getErrorPanel().getName());
				}
			} catch (Exception e) { }
		}
	}
	
	class CalculateFrequencyWorker extends SwingWorker<Word[], Void> {
		@Override
		protected Word[] doInBackground() throws Exception {
			getProgressPanel().setMessage("Calculating Word Frequency...");
			cardLayout.show(getCardPanel(), getProgressPanel().getName());
			
			//TODO: Add logic for determining sorted Word array based on frequency
			Thread.sleep(1000);
			return new Word[]{ new Word("HelloWord", 1) };
		}
		
		@Override
		protected void done() {
			try {
				if(get() != null) {
					//TODO: Enable statement below once logic is working
					//getWordSelectionPanel().clearWordElements();
					//getWordSelectionPanel().addWordElements(get(), 10);
					cardLayout.show(getCardPanel(), getWordSelectionPanel().getName());
				} else {
					getErrorPanel().setReturnCardName(getTagCloudPanel().getName());
					getErrorPanel().setError("Processing Error", "An error occured while processing this Tag Cloud. Please verify the file and try again later.");
					cardLayout.show(getCardPanel(), getErrorPanel().getName());
				}
			} catch (Exception e) { }
		}
	}
	
	class GenerateCloudWorker extends SwingWorker<String, Void> {
		@Override
		protected String doInBackground() throws Exception {
			getProgressPanel().setMessage("Generating Word Cloud...");
			cardLayout.show(getCardPanel(), getProgressPanel().getName());
			
			//TODO: Add logic for determining sorted Word array based on frequency
			Thread.sleep(1000);
			return "Hello World!";
		}
		
		@Override
		protected void done() {
			try {
				if(get() != null) {
					//TODO: Enable generation logic
					getOutputPanel().setHTML("<a href=\"http://tag\" onmouseover=\"this.style.color=\'#994dd1\'\" onmouseout=\"this.style.color=\'#afaf6f\'\" style=\"color:#afaf6f;font-size:24px;text-decoration:none\" title=\"Count: 51\">tag</a> <a href=\"http://cloud\" onmouseover=\"this.style.color=\'#5afa9c\'\" onmouseout=\"this.style.color=\'#ef2152\'\" style=\"color:#ef2152;font-size:25px;text-decoration:none\" title=\"Count: 58\">cloud</a> <a href=\"http://wikipedia\" onmouseover=\"this.style.color=\'#d8a55a\'\" onmouseout=\"this.style.color=\'#a071fd\'\" style=\"color:#a071fd;font-size:13px;text-decoration:none\" title=\"Count: 5\">wikipedia</a> <a href=\"http://free\" onmouseover=\"this.style.color=\'#2f881a\'\" onmouseout=\"this.style.color=\'#8081fb\'\" style=\"color:#8081fb;font-size:12px;text-decoration:none\" title=\"Count: 4\">free</a> <a href=\"http://color\" onmouseover=\"this.style.color=\'#f60d51\'\" onmouseout=\"this.style.color=\'#7c8fc5\'\" style=\"color:#7c8fc5;font-size:14px;text-decoration:none\" title=\"Count: 6\">color</a> <a href=\"http://search\" onmouseover=\"this.style.color=\'#649757\'\" onmouseout=\"this.style.color=\'#547500\'\" style=\"color:#547500;font-size:16px;text-decoration:none\" title=\"Count: 9\">search</a> <a href=\"http://terms\" onmouseover=\"this.style.color=\'#b205d5\'\" onmouseout=\"this.style.color=\'#f17b83\'\" style=\"color:#f17b83;font-size:11px;text-decoration:none\" title=\"Count: 3\">terms</a> <a href=\"http://web\" onmouseover=\"this.style.color=\'#eb3e23\'\" onmouseout=\"this.style.color=\'#51ae1b\'\" style=\"color:#51ae1b;font-size:15px;text-decoration:none\" title=\"Count: 7\">web</a> <a href=\"http://weighted\" onmouseover=\"this.style.color=\'#81d3a9\'\" onmouseout=\"this.style.color=\'#7934e2\'\" style=\"color:#7934e2;font-size:12px;text-decoration:none\" title=\"Count: 4\">weighted</a> <a href=\"http://list\" onmouseover=\"this.style.color=\'#c67d50\'\" onmouseout=\"this.style.color=\'#1de085\'\" style=\"color:#1de085;font-size:11px;text-decoration:none\" title=\"Count: 3\">list</a> <a href=\"http://visual\" onmouseover=\"this.style.color=\'#574d30\'\" onmouseout=\"this.style.color=\'#7fbdbe\'\" style=\"color:#7fbdbe;font-size:16px;text-decoration:none\" title=\"Count: 9\">visual</a> <a href=\"http://user\" onmouseover=\"this.style.color=\'#4766e3\'\" onmouseout=\"this.style.color=\'#c5cba8\'\" style=\"color:#c5cba8;font-size:14px;text-decoration:none\" title=\"Count: 6\">user</a> <a href=\"http://tags\" onmouseover=\"this.style.color=\'#dbbb78\'\" onmouseout=\"this.style.color=\'#2018d5\'\" style=\"color:#2018d5;font-size:19px;text-decoration:none\" title=\"Count: 17\">tags</a> <a href=\"http://word\" onmouseover=\"this.style.color=\'#5cc341\'\" onmouseout=\"this.style.color=\'#fe3c7d\'\" style=\"color:#fe3c7d;font-size:17px;text-decoration:none\" title=\"Count: 11\">word</a> <a href=\"http://content\" onmouseover=\"this.style.color=\'#b0c240\'\" onmouseout=\"this.style.color=\'# dfb74\'\" style=\"color:# dfb74;font-size:13px;text-decoration:none\" title=\"Count: 5\">content</a> <a href=\"http://site\" onmouseover=\"this.style.color=\'#b9c7c7\'\" onmouseout=\"this.style.color=\'#4a1011\'\" style=\"color:#4a1011;font-size:13px;text-decoration:none\" title=\"Count: 5\">site</a> <a href=\"http://used\" onmouseover=\"this.style.color=\'#bdaae3\'\" onmouseout=\"this.style.color=\'#14c263\'\" style=\"color:#14c263;font-size:16px;text-decoration:none\" title=\"Count: 9\">used</a> <a href=\"http://usually\" onmouseover=\"this.style.color=\'#393164\'\" onmouseout=\"this.style.color=\'#96503d\'\" style=\"color:#96503d;font-size:11px;text-decoration:none\" title=\"Count: 3\">usually</a> <a href=\"http://words\" onmouseover=\"this.style.color=\'#b53461\'\" onmouseout=\"this.style.color=\'#68b97f\'\" style=\"color:#68b97f;font-size:11px;text-decoration:none\" title=\"Count: 3\">words</a> <a href=\"http://font\" onmouseover=\"this.style.color=\'#16d239\'\" onmouseout=\"this.style.color=\'#ab41b3\'\" style=\"color:#ab41b3;font-size:16px;text-decoration:none\" title=\"Count: 8\">font</a> <a href=\"http://size\" onmouseover=\"this.style.color=\'#e54944\'\" onmouseout=\"this.style.color=\'#7b6991\'\" style=\"color:#7b6991;font-size:18px;text-decoration:none\" title=\"Count: 12\">size</a> <a href=\"http://popularity\" onmouseover=\"this.style.color=\'#ffb6b3\'\" onmouseout=\"this.style.color=\'#974f19\'\" style=\"color:#974f19;font-size:11px;text-decoration:none\" title=\"Count: 3\">popularity</a> <a href=\"http://items\" onmouseover=\"this.style.color=\'#6ce514\'\" onmouseout=\"this.style.color=\'#eaf4d6\'\" style=\"color:#eaf4d6;font-size:14px;text-decoration:none\" title=\"Count: 6\">items</a> <a href=\"http://data\" onmouseover=\"this.style.color=\'#e8fd35\'\" onmouseout=\"this.style.color=\'#eeb8be\'\" style=\"color:#eeb8be;font-size:18px;text-decoration:none\" title=\"Count: 12\">data</a> <a href=\"http://clouds \" onmouseover=\"this.style.color=\'#6429b9\'\" onmouseout=\"this.style.color=\'#af7a86\'\" style=\"color:#af7a86;font-size:14px;text-decoration:none\" title=\"Count: 6\">clouds </a> ");
					cardLayout.show(getCardPanel(), getOutputPanel().getName());
				} else {
					getErrorPanel().setReturnCardName(getTagCloudPanel().getName());
					getErrorPanel().setError("Generation Error", "An error occured while generating this Tag Cloud. Please try again later.");
					cardLayout.show(getCardPanel(), getErrorPanel().getName());
				}
			} catch (Exception e) { }
		}
	}

}